﻿/**
 * ...
 * @author Innokentiy Shuvalov
 * @author Alex
 */

package list;

import flash.net.URLRequest;
import loader.Loader; 
import list.DisplayMode;
import client.INews;
import client.Item;
import flash.geom.Rectangle;
import gui.hug.HUGSprite;
import gui.hug.HUGColors;
import flash.text.TextFormat;
import gui.hug.HUGTextArea;
import gui.hug.Utils;
import gui.hug.HUGLabel;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.ui.Keyboard;
import haxe.Timer;
import client.Channel;
import tab.FavoritesTab;

class ItemPanel extends HUGSprite {

	static private inline var SELECTED_BACKGROUND_COLOR : UInt = Utils.SEL_BG_COL;
	static private inline var SELECTED_BORDER_COLOR : UInt = Utils.SEL_BG_COL - 0x222222;
	static private inline var SELECTED_TEXT_COLOR : UInt = HUGColors.WHITE;
	static private inline var SELECTED_LINK_COLOR : UInt = HUGColors.VK_BUTTON - 0x222222;
	
	static private inline var HIGHLIGHTED_BACKGROUND_COLOR : UInt = HUGColors.VK_BORDER_INNER - 0x222211;
	static private inline var HIGHLIGHTED_BORDER_COLOR : UInt = Utils.SEL_BG_COL + 0x222222;
	static private inline var HIGHLIGHTED_TEXT_COLOR : UInt = 0x002266;
	static private inline var HIGHLIGHTED_LINK_COLOR : UInt = 0x004499;
	
	static private inline var DEFAULT_BACKGROUND_COLOR : UInt = HUGColors.VK_BORDER_INNER;
	static private inline var DEFAULT_BORDER_COLOR : UInt = HUGColors.WHITE;
	static private inline var DEFAULT_TEXT_COLOR : UInt = HUGColors.VK_MENU_TEXT;
	
	static private inline var TITLE_SIZE : UInt = 13;
	static private inline var TEXT_SIZE : UInt = 11;
	
	static private inline var TEXT_ADD_TO_FAVOURITES : String = "Добавлено в избранное";
	static private inline var str: String = "Добавить в избранное";
	
	static private var shortTitleFormat = new TextFormat("Tahoma", TITLE_SIZE, DEFAULT_TEXT_COLOR, true, false, true);
	static private var shortTextFormat = new TextFormat("Tahoma", TEXT_SIZE, DEFAULT_TEXT_COLOR, false, false, false);
	static private var selectedTitleFormat = new TextFormat("Tahoma", TITLE_SIZE, SELECTED_TEXT_COLOR, true, false, true);
	static private var selectedTextFormat = new TextFormat("Tahoma", TEXT_SIZE, SELECTED_TEXT_COLOR, false, false, false);
	static private var highlightedTitleFormat = new TextFormat("Tahoma", TITLE_SIZE, HIGHLIGHTED_TEXT_COLOR, true, false, true);
	static private var highlightedTextFormat = new TextFormat("Tahoma", TEXT_SIZE, HIGHLIGHTED_TEXT_COLOR, false, false, false);
	
	static private inline var IMAGE_HEIGHT   : UInt = 50;
	static private inline var IMAGE_WIDTH    : UInt = 50;
	private static inline var LEFT : Float =  6 + IMAGE_WIDTH;
	
	static private inline var SPACE_FROM_TOP 			: UInt = 3; 	// space before title
	static private inline var SPACE_AFTER_TITLE 		: UInt = 10;
	static private inline var SPACE_AFTER_DESCRIPTION 	: UInt = 8;
	static private inline var SPACE_AFTER_DATE 			: UInt = 8;
	
	private var w : UInt; //width
	private var addition : Float;
	private var shortNameHeight : Float;
	private var fullNameHeight : Float;
	private var fullDescriptionHeight : Float;
	private var shortDescriptionHeight : Float;

	
	// content
	private var content : INews;
	private var mode : DisplayMode;
	private var id : UInt;
	private var stateChanged : Bool;
	
	// graphical parts
	private var image :ImageLoader;
	private var fullName : HUGLabel;
	private var shortName : HUGLabel;
	private var fullDescription : HUGLabel;
	private var shortDescription : HUGLabel;
	private var date : HUGLabel;
	private var link : MyLinkButton;
	private var open : MyLinkButton;
	private var hideButton : MyLinkButton;
	private var toFriend : MyLinkButton;
	private var Add: MyLinkButton;
	public var Favorites: Array<INews>;
	private var loader : loader.Loader;
	private var dataId : Array<Int> ;

	
	public function new( panelWidth : UInt, item : INews, index : UInt, type:Int , ?disMode : DisplayMode ) {
		super();
		Favorites = new Array<INews>();
		Loader.createInstance();
		
		w = panelWidth;
		content = item;
		mode = disMode == null ? DisplayMode.short : disMode;
		id = index;
		
		addition = Std.is(content, Item) ? 0 : 150;
		
		init(type);
		generatePanel();
		
		addEventListener( MouseEvent.CLICK, onClick );
		addEventListener( MouseEvent.MOUSE_OVER, onOver );
		addEventListener( MouseEvent.MOUSE_OUT, onOut );
		addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );

	}
	
	private function init(type:Int) {
		stateChanged = true;
		
		initImage();
		initName();
		initDescription();
		initDate();
		initLink();
		initOpen(type);
		initHide(type);
		setLinkColor();
		
		initFavYesORNo(type);
		
		if (type == 1) initToFriend();
	}
	
	private function initFavYesORNo(type:Int) {
	    loader = Loader.getInstance();
		if (type==0) loader.getIDFavorites(onLoadFav);
		initAddFavorites(str, type);
	} 
	
	private function onLoadFav(data : Array < Int > ) :Void {
		
		for (channel in data)
		   if (content.getChanId() == channel) 
			 initAddFavorites(TEXT_ADD_TO_FAVOURITES, 0);	
		  				 
	}
	
	
	
	private function initImage() {
		image = new ImageLoader(Std.string(content.getLinkImg()), IMAGE_WIDTH, IMAGE_HEIGHT); // Loader.wrapImageLink()
		image.visible = true;
		image.x = 0;
		image.y = 0;
		addChild(image);
	}

	private function initName() {
		fullName = new HUGLabel();
		fullName.setTextFormat( shortTitleFormat );
		fullName.setLocation(LEFT , 0);
		fillFullName( content.getName() );
		fullName.visible = false;
		addChild(fullName);
		
		fullNameHeight = fullName.getBounds(fullName).height;
	
		shortName = new HUGLabel();
		shortName.setTextFormat( shortTitleFormat );
		shortName.setLocation(LEFT , 0);
		fillShortName( content.getName() );
		addChild(shortName);
		
		shortNameHeight = shortName.getBounds(shortName).height;
	}
	
	private function initDescription() {
		fullDescription = new HUGLabel();
		fullDescription.setLocation(LEFT ,  fullNameHeight + SPACE_AFTER_TITLE);
		fullDescription.setTextFormat( shortTextFormat );
		fullDescription.visible = false;
		fullDescription.multiline = true;
		fullDescription.text = "";
		fillFullDescription(content.getDescr() );
		addChild(fullDescription);
		
		fullDescriptionHeight = fullDescription.getBounds(fullDescription).height * 0.88;

		shortDescription = new HUGLabel();
		shortDescription.setLocation(LEFT , shortNameHeight + SPACE_AFTER_TITLE);
		shortDescription.setTextFormat( shortTextFormat );
		shortDescription.multiline = true;
		fillShortDescription( content.getDescr() );
		addChild(shortDescription);
		
		shortDescriptionHeight = 18 ; //shortDescription.getBounds(shortDescription).height ;
	}

	private function initDate() {
		date = new HUGLabel();
		date.setLocation(LEFT, fullNameHeight +
								SPACE_AFTER_TITLE + 
								fullDescriptionHeight + 
								SPACE_AFTER_DESCRIPTION );
		
		date.visible = false;
		date.text = content.getDate();
		date.setTextFormat( shortTextFormat );
		addChild(date);
	}

	private function initLink() {
		link = new MyLinkButton();
		link.setNewText("Открыть в браузере");
		link.addEventListener( MouseEvent.CLICK, openLink );
		link.setLocation(LEFT, 	fullNameHeight +
								SPACE_AFTER_TITLE + 
								fullDescriptionHeight + 
								SPACE_AFTER_DESCRIPTION + 
								date.getBounds(date).height + 
								SPACE_AFTER_DATE );
		link.visible = false;
		addChild(link);
	}
	
	private function initToFriend() {
		
		toFriend = new MyLinkButton();
		toFriend.setNewText("Отправить другу");
		toFriend.addEventListener(MouseEvent.CLICK, onSend);
		toFriend.setLocation(LEFT + link.width + 10 + open.width + 10, 	fullNameHeight + SPACE_AFTER_TITLE + fullDescriptionHeight + SPACE_AFTER_DESCRIPTION + 
		date.getBounds(date).height + SPACE_AFTER_DATE );
		toFriend.visible = false;
		addChild(toFriend);
	
	}

	private function initOpen(type:Int) {
		open = new MyLinkButton();	
		open.setNewText("Открыть");
		open.addEventListener( MouseEvent.CLICK, openTab );
		open.setLocation(LEFT + link.width + 10, 	fullNameHeight +
											SPACE_AFTER_TITLE + 
											fullDescriptionHeight + 
											SPACE_AFTER_DESCRIPTION + 
											date.getBounds(date).height + 
											SPACE_AFTER_DATE );
		open.visible = !Std.is(content, Item);
		if(type == 0)
		addChild(open);
	}

	private function initHide(type:Int) {
		hideButton = new MyLinkButton();
		hideButton.setNewText("Убрать");
		hideButton.addEventListener( MouseEvent.CLICK, onHide );
		if(type==0 )
		hideButton.setLocation(LEFT + link.width + 10 + open.width + 10, 	fullNameHeight +
														SPACE_AFTER_TITLE + 
														fullDescriptionHeight + 
														SPACE_AFTER_DESCRIPTION + 
														date.getBounds(date).height + 
														SPACE_AFTER_DATE );
        else	
		hideButton.setLocation(link.x+link.width+10,link.y );
		hideButton.visible = false;
		addChild(hideButton);
	}
	public function initAddFavorites(str:String, type:Int) {
	    Add = new MyLinkButton();
		Add.setNewText(str);
		
		if (str!=TEXT_ADD_TO_FAVOURITES)
		{Add.addEventListener( MouseEvent.CLICK, AddChan); }
		
		Add.setLocation(hideButton.x+hideButton.width+10,hideButton.y );
		Add.visible = !Std.is(content, Item);
		if(type==0)
		addChild(Add);
	}
	
	// USER METHODS /////////////////////////////////////////////////////////////////////////
	
	public function getContent() : INews {
		return content;
	}
	
	public function reduceId() {
		if (id > 0) {
			id -- ;
		}
	}
	
	public function getHeight() : Float {
		return switch(mode) {
			case(DisplayMode.hidden) : 0 ;
			case(DisplayMode.short) :
				shortNameHeight +
				SPACE_AFTER_TITLE + 
				shortDescriptionHeight + 
				5 ;
			case(DisplayMode.selected) :
				fullNameHeight +
				SPACE_AFTER_TITLE + 
				fullDescriptionHeight + 
				SPACE_AFTER_DESCRIPTION + 
				date.getBounds(date).height + 
				SPACE_AFTER_DATE +
				hideButton.getBounds(hideButton).height +
				10 ;
			case(DisplayMode.highlighted) :
				shortNameHeight +
				SPACE_AFTER_TITLE + 
				shortDescriptionHeight + 
				5 ;
		}
	}
	
	/**
	 * @param	hidden	in case it is 'true' the item becomes hidden
	 * and only a one more execution of this method with 'false' parameter
	 * can make it visible again!
	 */
	public function hide( hidden : Bool = true ) {
		if (hidden) setDisplayMode(DisplayMode.hidden);
		else setDisplayMode(DisplayMode.short);
	}
	
	
	// PRIVATE METHODS //////////////////////////////////////////////////////////////////
	
	private function generatePanel() {
		if (stateChanged) {
			drawBackground();
			//setLinkColor();
			setVisibleElements();
			setLabelFormats();
			stateChanged = false;
		}
	}
	
	private function setLabelFormats() {
		if (stateChanged) {
			switch(mode) {
				case DisplayMode.short :
					shortName.setTextFormat(shortTitleFormat);
					shortDescription.setTextFormat(shortTextFormat);
					date.setTextFormat(shortTextFormat);
				case DisplayMode.selected :
					fullName.setTextFormat(selectedTitleFormat);
					fullDescription.setTextFormat(selectedTextFormat);
					date.setTextFormat(selectedTextFormat);
				case DisplayMode.highlighted :
					shortName.setTextFormat(highlightedTitleFormat);
					fullDescription.setTextFormat(highlightedTextFormat);
					shortDescription.setTextFormat(highlightedTextFormat);
					date.setTextFormat(highlightedTextFormat);
			}
		}
	}
	
	private function setVisibleElements() {
		if (stateChanged) {
			var visibility = mode == DisplayMode.selected;
			date.visible = visibility;
			open.visible = visibility;
			link.visible = visibility;
			hideButton.visible = visibility;
			fullDescription.visible = visibility;
			shortDescription.visible = !visibility;
			fullName.visible = visibility;
			shortName.visible = !visibility;
			Add.visible = visibility;
			if (toFriend != null) toFriend.visible = visibility;
		}
	} 
	
	private function drawBackground() {
		if (stateChanged) {
			var backgroundColor = DEFAULT_BACKGROUND_COLOR;
			var borderColor = DEFAULT_BORDER_COLOR;
			switch(mode) {
				case DisplayMode.selected : 
					backgroundColor = SELECTED_BACKGROUND_COLOR;
					borderColor = SELECTED_BORDER_COLOR;
				case DisplayMode.highlighted : 
					backgroundColor = HIGHLIGHTED_BACKGROUND_COLOR;
					borderColor = HIGHLIGHTED_BORDER_COLOR;
			}
			Utils.rect( this,	// owner
						0,		// left
						0,		// top
						w,
						getHeight(),
						backgroundColor,
						borderColor );
		}
	}
	
	private function setLinkColor() {
		if (stateChanged) switch(mode) {
			case DisplayMode.selected : 
				link.setOverStateColor(SELECTED_LINK_COLOR);
				open.setOverStateColor(SELECTED_LINK_COLOR);
				hideButton.setOverStateColor(SELECTED_LINK_COLOR);
				Add.setOverStateColor(SELECTED_LINK_COLOR);
			case DisplayMode.highlighted : 
				link.setOverStateColor(HIGHLIGHTED_LINK_COLOR);
				open.setOverStateColor(HIGHLIGHTED_LINK_COLOR);
				hideButton.setOverStateColor(HIGHLIGHTED_LINK_COLOR);
				Add.setOverStateColor(HIGHLIGHTED_LINK_COLOR);
		}
	}
	
	private function setDisplayMode ( m : DisplayMode ) {
		if ( mode != m ) {
			stateChanged = true;
			mode = m;
		}
		generatePanel();
	}
	
	/**
	* we need to edit the description
	* because it might be too long
	* and so any parts will be missing.
	*/
	private function fillFullDescription(textDescription : String) {
		var text : String = StringTools.htmlUnescape(deleteTags(StringTools.htmlUnescape(textDescription)));
		var rememberText = fullDescription.text;
		fullDescription.text = "";
		
		for (i in 0 ... text.length) {
			if (text.charAt(i) != "\n")
				fullDescription.appendText(text.charAt(i) );
			if (fullDescription.getBounds(fullDescription).width * 1.3 + fullDescription.x > w ||
				text.charAt(i) == "\n" ) {
			
				fullDescription.text = rememberText + fullDescription.text + "\n";
				if( i != text.length - 1) fillFullDescription(text.substr(i + 1));
				return;
			}
		}
		fullDescription.text = rememberText + fullDescription.text + "\n";
	}
	
	/**
	* we need to edit the description
	* because it might be too long
	* and so it won't be convenient
	* to display the whole one.
	*/
	private function fillShortDescription(textDescription : String) {
		var text : String = StringTools.htmlUnescape(deleteTags(StringTools.htmlUnescape(textDescription)));
		shortDescription.text = "";
		for (i in 0 ... text.length) {
			if (text.charAt(i) != "\n")
				shortDescription.appendText(text.charAt(i) );
			if (shortDescription.getBounds(shortDescription).width * 1.14 + shortDescription.x  > w ||
				text.charAt(i) == "\n") {
				if( i != text.length - 1) shortDescription.appendText("...");
				return;
			}
		}
	}
	
	/**
	* we need to edit the name
	* because it might be too long
	* and so any parts will be missing.
	*/
	private function fillFullName(text : String) {
		var rememberText = fullName.text;
		fullName.text = "";
		
		for (i in 0 ... text.length) {
			if (text.charAt(i) != "\n")
				fullName.appendText(text.charAt(i) );
			if (fullName.getBounds(fullName).width * 1.5 + fullName.x > w ||
				text.charAt(i) == "\n" ) {
			
				fullName.text = rememberText + fullName.text + "\n";
				if( i != text.length - 1) fillFullName(text.substr(i + 1));
				return;
			}
		}
		fullName.text = rememberText + fullName.text + "\n";
	}
	
	/**
	* we need to edit the name
	* because it might be too long
	* and so it won't be convenient
	* to display the whole one.
	*/
	private function fillShortName(text : String) {
		shortName.text = "";
		for (i in 0 ... text.length) {
			if (text.charAt(i) != "\n")
				shortName.appendText(text.charAt(i) );
			if (shortName.getBounds(shortName).width * 1.5 + shortName.x > w ||
				text.charAt(i) == "\n") {
				if( i != text.length - 1) shortName.appendText("...");
				return;
			}
		}
	}
	
	
	private function deleteTags(text : String):String {
		var re : EReg = ~/<\/?[A-Za-z]+\/?>/g ;
		return re.replace(text, "");		 
	}
	
	// EVENT HANDLERS ///////////////////////////////////////////////////
	
	private function onClick(_) {
		if (mode != DisplayMode.hidden) {
			if ( mode != DisplayMode.selected ) setDisplayMode(DisplayMode.selected);
			else setDisplayMode(DisplayMode.highlighted);
		
			cast(parent, NewList).scrollTo(id);
			cast(parent, NewList).draw();
			
		}
	}
	
	private function onOver(_) {
		if (mode != DisplayMode.hidden) {
			if ( mode != DisplayMode.selected ) setDisplayMode(DisplayMode.highlighted);
			cast(parent, NewList).scrollTo(id);
			cast(parent, NewList).draw();
		}
	}
	
	private function onOut(_) {
		if (mode != DisplayMode.hidden) {
			if ( mode != DisplayMode.selected ) setDisplayMode(DisplayMode.short);
			cast(parent, NewList).draw();
		}
	}
	
	private function openLink(e : MouseEvent) {
		flash.Lib.getURL(new URLRequest(content.getLink()));
		e.stopPropagation();
	}
	
	private function openTab(e : MouseEvent) {
		cast(parent, NewList).dispatchEvent(new OpenTabEvent(content));
		e.stopPropagation();
	}
	
	private function onHide(e : MouseEvent) {
		hide();
		cast(parent, NewList).draw();
		e.stopPropagation();
	}
	
	private function onSend(e : MouseEvent) {
		var friendList : FriendList = new FriendList();
		var names : Array < String > = new Array();
		var ids : Array < Int > = new Array(); 
		var me = this;
		Loader.apiRequest.getAppFriends(function(e : Array < Int > ) { ids = e; trace("ok");
		
		Loader.apiRequest.getProfiles(ids, function(t : Array < Dynamic > ) {
			for (i in 0...ids.length) {
				names[i] = "" + t[i].firstName +"   " + t[i].lastName;
				trace(ids[i]);
			}
			
			for (i in 0...names.length) {
				friendList.addFriend(names[i], ids[i], cast(cast(me.getContent(), Item).getItemID()));
			}
			var S : Sprite = new Sprite();
			S.addChild(friendList);
			me.parent.parent.addChild(S);
			S.visible = true;
			
			
		}, function(f : String) { trace(f); } );
		
		}, function(s : String) { trace(s); } );
		
		//здесь будет запрос id и имен друзей юзера, установивших приложение 
		//names.push("name1 surname1"); names.push("name2 surname2");
		//ids.push(1); ids.push(2);
		
	}
	
	private function AddChan(e: MouseEvent) {
		Add.setNewText("Добавлено в избранное");
		Favorites.push(this.getContent());
		loader.AddToFavorites(content.getChanId());
		e.stopPropagation();
	}
	
	private function onKeyDown ( e : KeyboardEvent ) {
		switch ( e.keyCode ) {
			case Keyboard.UP : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.UP));
			case Keyboard.DOWN : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.DOWN));
			case Keyboard.PAGE_DOWN : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.PAGE_DOWN));
			case Keyboard.PAGE_UP : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.PAGE_UP));
			case Keyboard.END : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.END));
			case Keyboard.HOME : cast(parent, NewList).dispatchEvent(new ScrollEvent(ScrollEvent.HOME));
		}
	}
}